using System;
using System.Text;
using System.Diagnostics;
using System.Collections.Generic;
using System.Collections.Specialized;

namespace My.IdlConverter.Core.Graphics
{
    using Parsers;
    using Cfg;

    public class ClassForest
    {
        private static ClassForest _instance;
        private static IList<ClassTree> _classTrees = new List<ClassTree>();

        static ClassForest()
        {
            _instance = new ClassForest();

            IList<Class> finalClasses = new List<Class>();
            Util.IOHelper.PathNameFilterFun filter = new Util.IOHelper.PathNameFilterFun(Util.Delegators.FilterClassFileFunc);
            StringCollection files = Util.IOHelper.GetCppHeaderFiles(Configuration.ClassFolder, filter, false);

            IParser classParser = new ClassParser();
            Class classObj = null;
            foreach (string nextFile in files)
            {
                Trace.WriteLine(nextFile);

                classObj = classParser.Parse(nextFile) as Class;
                if (classObj != null)
                {
                    if (classObj.IsFinal())
                        finalClasses.Add(classObj);
                }
            }

            foreach (Class nextClassObj in finalClasses)
            {
                ClassTree tree = new ClassTree(nextClassObj);
                BuildTree(tree, nextClassObj);
                _classTrees.Add(tree);
            }
        }

        private ClassForest()
        {
        }

        public static ClassForest Instance
        {
            get
            {
                return _instance;
            }
        }

        public IList<ClassTree> ChildTrees
        {
            get
            {
                return _classTrees;
            }
        }

        private static void BuildTree(ClassNode parent, Class classObj)
        {
            Debug.Assert(classObj.IsClass());

            IList<Interface> baseInerfaces = classObj.BaseInterfaces;
            foreach (Interface nextInterface in baseInerfaces)
            {
                if (nextInterface == null)
                    continue;
                if (nextInterface.IsClass())
                {
                    Class nextClassObj = nextInterface as Class;
                    Debug.Assert(nextClassObj != null);
                    ClassNode parentNode = new ClassNode(nextClassObj,parent);
                    parent.ChildNodes.Add(parentNode);
                    BuildTree(parentNode, nextClassObj);
                }
                else
                {
                    parent.ChildNodes.Add(new ClassNode(nextInterface, parent));
                }
            }
        }
    }
}
